home *** CD-ROM | disk | FTP | other *** search
- /* The go player utilities */
- /* Ported from Pascal to C by Todd R. Johnson */
- /* From the original Pascal file:
- Copyright (c) 1983 by Three Rivers Computer Corp.
-
- Written: January 17, 1983 by Stoney Ballard
- */
-
- #include "goplayutils.h"
- #include "amigo.h"
- #include "go.h"
-
- extern struct bRec goboard[19][19];
-
- intBoard claim, extra, bord, ndbord, sGroups, threatBord,
- groupIDs, connectMap, protPoints;
- boolBoard groupSeen, legal;
- short maxGroupID;
- pointList pList, pList1, plist2, plist3, pPlist;
- intList nlcGroup, aList;
- sgRec sList[401];
- groupRec gList[maxGroup];
- short killFlag,
- numCapt,
- utilPlayLevel,
- treeLibLim;
- sType mySType;
- short showTrees;
- short sGlist[maxGroup+1];
- short depthLimit;
- intBoard markBoard;
- short marker;
-
- short adjInAtari, adj2Libs,
- intersectNum, spanNum, libMark;
- playRec playStack[1025];
- short playMark,
- newGID,
- tryLevel,
- grpMark,
- gMap[maxGroup];
- short dbStop, inGenState;
-
- pause()
- { /* pause */
- /* if (dbStop and ! inGenState)
- {
- while ! tabswitch do;
- repeat
- if (tabYellow)
- dbStop = false;
- until ! tabswitch;
- } */
- } /* pause */
-
- sstone(w, x, y, numb)
- short w, x, y, numb;
- { /* sstone */
- if (w == 1)
- placestone(mySType, x, y);
- else if (mySType == WHITE)
- placestone(BLACK, x, y);
- else
- placestone(WHITE, x, y);
- } /* sstone */
-
- rstone(x, y)
- short x, y;
- { /* rstone */
- removestone(x, y);
- } /* rstone */
-
- initBoolBoard(bb)
- boolBoard bb;
- { /* initBoolBoard */
- short i, j;
- #ifdef DEBUG
- printf( "initBoolBoard\n" );
- #endif
- for (i = 0; i <= maxPoint; i++)
- for (j = 0; j <= maxPoint; j++)
- bb[i][j] = FALSE;
- } /* initBoolBoard */
-
- sortLibs()
- { /* sortLibs */
- short i, j, t;
- #ifdef DEBUG
- printf( "sortLibs\n" );
- #endif
- for (i = 1; i <= maxGroupID; i++)
- sGlist[i] = i;
- for (i = 1; i < maxGroupID; i++)
- for (j = i + 1; j <= maxGroupID; j++)
- if (gList[sGlist[i]].libC > gList[sGlist[j]].libC)
- {
- t = sGlist[i];
- sGlist[i] = sGlist[j];
- sGlist[j] = t;
- }
- } /* sortLibs */
-
- spanGroupspan(x, y, libs, lookFor)
- short x, y, lookFor;
- pointList *libs;
- { /* span */
- markBoard[x][y] = marker;
- if (bord[x][y] == 0)
- {
- libs->indx = libs->indx + 1;
- libs->p[libs->indx].px = x;
- libs->p[libs->indx].py = y;
- }
- else if (bord[x][y] == lookFor)
- {
- groupSeen[x][y] = TRUE;
- if ((x > 0) && (markBoard[x - 1][y] != marker))
- spanGroupspan(x - 1, y, libs, lookFor);
- if ((y > 0) && (markBoard[x][y - 1] != marker))
- spanGroupspan(x, y - 1, libs, lookFor);
- if ((x < maxPoint) && (markBoard[x + 1][y] != marker))
- spanGroupspan(x + 1, y, libs, lookFor);
- if ((y < maxPoint) && (markBoard[x][y + 1] != marker))
- spanGroupspan(x, y + 1, libs, lookFor);
- }
- else if (gList[gMap[groupIDs[x][y]]].libC == 1)
- adjInAtari = TRUE;
- else if ((gList[gMap[groupIDs[x][y]]].libC == 2) &&
- (! gList[gMap[groupIDs[x][y]]].isLive))
- adj2Libs = TRUE;
- } /* span */
-
- spanGroup(x, y, libs)
- short x, y;
- pointList *libs;
- { /* spanGroup */
- short lookFor;
- #ifdef DEBUG
- printf( "spanGroup\n" );
- #endif
- marker = marker + 1;
- if (marker == 0)
- {
- initArray(markBoard);
- marker = 1;
- }
- adjInAtari = FALSE;
- adj2Libs = FALSE;
- lookFor = bord[x][y];
- libs->indx = 0;
- spanGroupspan(x, y, libs, lookFor);
- } /* spanGroup */
-
- sSpanGroupspan(x, y, libs, lookFor)
- short x, y, lookFor;
- sPointList *libs;
- { /* span */
- markBoard[x][y] = marker;
- if (bord[x][y] == 0)
- {
- libs->indx += 1;
- if (libs->indx <= maxSPoint)
- {
- libs->p[libs->indx].px = x;
- libs->p[libs->indx].py = y;
- }
- }
- else if (bord[x][y] == lookFor)
- {
- groupSeen[x][y] = TRUE;
- if ((x > 0) && (markBoard[x - 1][y] != marker))
- sSpanGroupspan(x - 1, y, libs, lookFor);
- if ((y > 0) && (markBoard[x][y - 1] != marker))
- sSpanGroupspan(x, y - 1, libs, lookFor);
- if ((x < maxPoint) && (markBoard[x + 1][y] != marker))
- sSpanGroupspan(x + 1, y, libs, lookFor);
- if ((y < maxPoint) && (markBoard[x][y + 1] != marker))
- sSpanGroupspan(x, y + 1, libs, lookFor);
- }
- else if (gList[gMap[groupIDs[x][y]]].libC == 1)
- adjInAtari = TRUE;
- else if ((gList[gMap[groupIDs[x][y]]].libC == 2) &&
- (! gList[gMap[groupIDs[x][y]]].isLive))
- adj2Libs = TRUE;
- } /* span */
-
- sSpanGroup(x, y, libs)
- short x, y;
- sPointList *libs;
- { /* sSpanGroup */
- short lookFor;
- #ifdef DEBUG
- printf( "sSpanGroup\n" );
- #endif
- marker = marker + 1;
- if (marker == 0)
- {
- initArray(markBoard);
- marker = 1;
- }
- adjInAtari = FALSE;
- adj2Libs = FALSE;
- lookFor = bord[x][y];
- libs->indx = 0;
- sSpanGroupspan(x, y, libs, lookFor);
- } /* sSpanGroup */
-
- LAspan(x, y, me, him, iL)
- short x, y, me, him;
- intList *iL;
- { /* span */
- #ifdef DEBUG
- printf( "LAspan\n" );
- #endif
- markBoard[x][y] = marker;
- if (bord[x][y] == me)
- {
- if ((x > 0) && (markBoard[x - 1][y] != marker))
- LAspan(x - 1, y, me, him, iL);
- if ((x < maxPoint) && (markBoard[x + 1][y] != marker))
- LAspan(x + 1, y, me, him, iL);
- if ((y > 0) && (markBoard[x][y - 1] != marker))
- LAspan(x, y - 1, me, him, iL);
- if ((y < maxPoint) && (markBoard[x][y + 1] != marker))
- LAspan(x, y + 1, me, him, iL);
- }
- else if (bord[x][y] == him)
- if (gList[gMap[groupIDs[x][y]]].groupMark != grpMark)
- {
- gList[gMap[groupIDs[x][y]]].groupMark = grpMark;
- iL->indx = iL->indx + 1;
- iL->v[iL->indx] = gMap[groupIDs[x][y]];
- }
- } /* span */
-
- listAdjacents(x, y, iL)
- short x, y;
- intList *iL;
- { /* listAdjacents */
- short me, him;
- #ifdef DEBUG
- printf( "listAdjacents\n" );
- #endif
- grpMark = grpMark + 1;
- marker = marker + 1;
- if (marker == 0)
- {
- initArray(markBoard);
- marker = 1;
- }
- iL->indx = 0;
- me = bord[x][y];
- him = -me;
- LAspan(x, y, me , him, iL);
- } /* listAdjacents */
-
- LDspan(x, y, me, diags)
- short x, y, me;
- sPointList *diags;
- { /* span */
- #ifdef DEBUG
- printf( "LDspan\n" );
- #endif
- markBoard[x][y] = marker;
- if ((x > 0) && (y > 0) &&
- (bord[x - 1][y - 1] == 0) &&
- (bord[x][y - 1] != me) &&
- (bord[x - 1][y] != me) &&
- (markBoard[x - 1][y - 1] != marker))
- {
- markBoard[x - 1][y - 1] = marker;
- diags->indx = diags->indx + 1;
- if (diags->indx <= maxSPoint)
- {
- diags->p[diags->indx].px = x - 1;
- diags->p[diags->indx].py = y - 1;
- }
- }
- if ((x < maxPoint) && (y > 0) &&
- (bord[x + 1][y - 1] == 0) &&
- (bord[x][y - 1] != me) &&
- (bord[x + 1][y] != me) &&
- (markBoard[x + 1][y - 1] != marker))
- {
- markBoard[x + 1][y - 1] = marker;
- diags->indx = diags->indx + 1;
- if (diags->indx <= maxSPoint)
- {
- diags->p[diags->indx].px = x + 1;
- diags->p[diags->indx].py = y - 1;
- }
- }
- if ((x > 0) && (y < maxPoint) &&
- (bord[x - 1][y + 1] == 0) &&
- (bord[x][y + 1] != me) &&
- (bord[x - 1][y] != me) &&
- (markBoard[x - 1][y + 1] != marker))
- {
- markBoard[x - 1][y + 1] = marker;
- diags->indx = diags->indx + 1;
- if (diags->indx <= maxSPoint)
- {
- diags->p[diags->indx].px = x - 1;
- diags->p[diags->indx].py = y + 1;
- }
- }
- if ((x < maxPoint) && (y < maxPoint) &&
- (bord[x + 1][y + 1] == 0) &&
- (bord[x][y + 1] != me) &&
- (bord[x + 1][y] != me) &&
- (markBoard[x + 1][y + 1] != marker))
- {
- markBoard[x + 1][y + 1] = marker;
- diags->indx = diags->indx + 1;
- if (diags->indx <= maxSPoint)
- {
- diags->p[diags->indx].px = x + 1;
- diags->p[diags->indx].py = y + 1;
- }
- }
- if ((x > 0) && (bord[x - 1][y] == me) &&
- (markBoard[x - 1][y] != marker))
- LDspan(x - 1, y, me, diags);
- if ((x < maxPoint) && (bord[x + 1][y] == me) &&
- (markBoard[x + 1][y] != marker))
- LDspan(x + 1, y, me, diags);
- if ((y > 0) && (bord[x][y - 1] == me) &&
- (markBoard[x][y - 1] != marker))
- LDspan(x, y - 1, me, diags);
- if ((y < maxPoint) && (bord[x][y + 1] == me) &&
- (markBoard[x][y + 1] != marker))
- LDspan(x, y + 1, me , diags);
- } /* span */
-
- listDiags(x, y, diags)
- short x, y;
- sPointList *diags;
- { /* listDiags */
- short me;
- #ifdef DEBUG
- printf( "listDiags\n" );
- #endif
- me = bord[x][y];
- diags->indx = 0;
- marker = marker + 1;
- if (marker == 0)
- {
- initArray(markBoard);
- marker = 1;
- }
- LDspan(x, y, me, diags);
- } /* listDiags */
-
- intersectPlist(p1, p2, pr)
- pointList *p1, *p2, *pr;
- { /* intersectPlist */
- short i, j, k;
- #ifdef DEBUG
- printf( "intersectPlist\n" );
- #endif
- marker = marker + 1;
- if (marker == 0)
- {
- initArray(markBoard);
- marker = 1;
- }
- pr->indx = 0;
- for (i = 1; i <= p1->indx; i++)
- markBoard[p1->p[i].px][p1->p[i].py] = marker;
- j = 0;
- for (i = 1; i <= p2->indx; i++)
- if (markBoard[p2->p[i].px][p2->p[i].py] == marker)
- {
- j = j + 1;
- pr->p[j] = p2->p[i];
- }
- pr->indx = j;
- } /* intersectPlist */
-
- initArray(ary)
- intBoard ary;
- { /* initArray */
- short i, j;
- for (i = 0; i <= maxPoint; i++)
- for (j = 0; j <= maxPoint; j++)
- ary[i][j] = 0;
- } /* initArray */
-
- initState()
- { /* initState */
- short i, j;
- for (i = 0; i <= maxPoint; i++)
- for (j = 0; j <= maxPoint; j++)
- {
- extra[i][j] = 0;
- claim[i][j] = 0;
- groupIDs[i][j] = 0;
- connectMap[i][j] = 0;
- protPoints[i][j] = 0;
- }
- } /* initState */
-
- copyArray( dest, src )
- intBoard dest, src;
- {
- short x, y;
- for (y = 0; y <= maxPoint; y++)
- for (x = 0; x <= maxPoint; x++)
- dest[x][y] = src[x][y];
- }
-
- /*
- generates a one-point spread in the force field array (claim)
-
- the spread from a single point after four calls is:
-
- 1
- 2 2 2
- 2 4 6 4 2
- 2 4 8 10 8 4 2
- 1 2 6 10 62 10 6 2 1
- 2 4 8 10 8 4 2
- 2 4 6 4 2
- 2 2 2
- 1
-
- */
- stake()
- {
- short x, y;
- initArray( extra );
- for (y = 0; y <= maxPoint; y++)
- for (x = 0; x <= maxPoint; x++)
- {
- extra[x][y] = extra[x][y] + claim[x][y];
- if (claim[x][y] > 0)
- {
- if (x > 0) extra[x-1][y] += 1;
- if (y > 0) extra[x][y-1] += 1;
- if (x < maxPoint) extra[x+1][y] += 1;
- if (y < maxPoint) extra[x][y+1] += 1;
- }
- else if (claim[x][y] < 0)
- {
- if (x > 0) extra[x-1][y] -= 1;
- if (y > 0) extra[x][y-1] -= 1;
- if (x < maxPoint) extra[x+1][y] -= 1;
- if (y < maxPoint) extra[x][y+1] -= 1;
- }
- }
- copyArray( claim, extra );
- } /* stake */
-
- /*
- sets up claim from the current board position
- */
- spread()
- {
- short x, y;
- for (y = 0; y <= maxPoint; y++)
- for (x = 0; x <= maxPoint; x++)
- claim[x][y] = ndbord[x][y] * 50;
- stake();
- stake();
- stake();
- stake();
- } /* spread */
-
- /*
- gList is initialized with the size, loc, and libCount of each group
- groupIDs contains the serial numbers of the groups.
- */
- Resspan(x, y, gID, gSize, libCount, who)
- short x, y, gID, *gSize, *libCount, who;
- { /* span */
- if ((bord[x][y] == 0) &&
- (markBoard[x][y] != marker)) /* a liberty */
- {
- markBoard[x][y] = marker;
- *libCount = *libCount + 1;
- }
- else if ((bord[x][y] == who) &&
- (groupIDs[x][y] == 0))
- {
- groupIDs[x][y] = gID;
- *gSize = *gSize + 1;
- if (x > 0)
- Resspan(x - 1, y, gID, gSize, libCount, who);
- if (x < maxPoint)
- Resspan(x + 1, y, gID, gSize, libCount, who);
- if (y > 0)
- Resspan(x, y - 1, gID, gSize, libCount, who);
- if (y < maxPoint)
- Resspan(x, y + 1, gID, gSize, libCount, who);
- }
- } /* span */
-
- respreicen()
- { /* respreicen */
- short i, j, gID, libCount, gSize, who;
- gID = 0;
- #ifdef DEBUG
- printf( "respreicen\n" );
- #endif
- for (i = 0; i <= maxPoint; i++)
- for (j = 0; j <= maxPoint; j++)
- groupIDs[i][j] = 0;
- for (i = 0; i <= maxPoint; i++)
- for (j = 0; j <= maxPoint; j++)
- if ((bord[i][j] != 0) && /* a stone there */
- (groupIDs[i][j] == 0)) /* not seen yet */
- {
- marker = marker + 1;
- if (marker == 0)
- {
- initArray(markBoard);
- marker = 1;
- }
- gID = gID + 1;
- libCount = 0;
- gSize = 0;
- who = bord[i][j];
- Resspan(i, j, gID, &gSize, &libCount, who); /* span the group, collecting info */
- gList[gID].groupMark = 0;
- gList[gID].atLevel = 0;
- gList[gID].isLive = FALSE; /* we don't know yet */
- gList[gID].isDead = FALSE;
- gList[gID].numEyes = -1;
- gList[gID].size = gSize;
- gList[gID].libC = libCount;
- gList[gID].lx = i;
- gList[gID].ly = j;
- gMap[gID] = gID; /* set up identity map */
- }
- maxGroupID = gID;
- newGID = gID;
- grpMark = 0;
- } /* respreicen */
-
- /*
- play z at [x, y].
- killFlag is set true if anything is killed.
- */
- killGroup(x, y, me, him)
- short x, y, me, him;
- { /* killGroup */
- #ifdef DEBUG
- printf( "killGroup\n" );
- #endif
- playMark = playMark + 1;
- /* record this kill */
- playStack[playMark].kind = rem;
- playStack[playMark].uval.rem.who = him;
- playStack[playMark].uval.rem.xl = x;
- playStack[playMark].uval.rem.yl = y;
- playStack[playMark].gID = groupIDs[x][y];
- playStack[playMark].uval.rem.sNumber = goboard[x][y].mNum;
- if (showTrees)
- rstone(x, y);
- numCapt = numCapt + 1;
- bord[x][y] = 0;
- groupIDs[x][y] = 0;
- if (x > 0)
- {
- if (bord[x - 1][y] == me)
- {
- nlcGroup.indx = nlcGroup.indx + 1;
- nlcGroup.v[nlcGroup.indx] = gMap[groupIDs[x - 1][y]];
- }
- else if (bord[x - 1][y] == him)
- killGroup(x - 1, y, me , him);
- }
- if (x < maxPoint)
- {
- if (bord[x + 1][y] == me)
- {
- nlcGroup.indx = nlcGroup.indx + 1;
- nlcGroup.v[nlcGroup.indx] = gMap[groupIDs[x + 1][y]];
- }
- else if (bord[x + 1][y] == him)
- killGroup(x + 1, y, me, him);
- }
- if (y > 0)
- {
- if (bord[x][y - 1] == me)
- {
- nlcGroup.indx = nlcGroup.indx + 1;
- nlcGroup.v[nlcGroup.indx] = gMap[groupIDs[x][y - 1]];
- }
- else if (bord[x][y - 1] == him)
- killGroup(x, y - 1, me, him);
- }
- if (y < maxPoint)
- {
- if (bord[x][y + 1] == me)
- {
- nlcGroup.indx = nlcGroup.indx + 1;
- nlcGroup.v[nlcGroup.indx] = gMap[groupIDs[x][y + 1]];
- }
- else if (bord[x][y + 1] == him)
- killGroup(x, y + 1, me, him);
- }
- } /* killGroup */
-
- mergeGroup(sGID, myGID)
- short sGID, myGID;
- { /* mergeGroup */
- short i;
- #ifdef DEBUG
- printf( "mergeGroup\n" );
- #endif
- for (i = 1; i <= newGID; i++)
- if (gMap[i] == sGID)
- {
- playMark = playMark + 1;
- playStack[playMark].kind = reMap;
- playStack[playMark].gID = i;
- playStack[playMark].uval.reMap.oldGID = sGID;
- gMap[i] = myGID;
- }
- } /* mergeGroup */
-
- tryPlay(x, y, z)
- short x, y, z;
- { /* plei */
- short i, me, him, myGID;
- short isNew;
- #ifdef DEBUG
- printf( "tryPlay\n" );
- #endif
- me = z;
- him = -me;
- killFlag = FALSE; /* set true if something is killed */
- numCapt = 0;
- tryLevel = tryLevel + 1;
- isNew = FALSE;
- bord[x][y] = z; /* play the stone */
- if ((x > 0) && (bord[x - 1][y] == me)) /* connect to adjacent group */
- myGID = gMap[groupIDs[x - 1][y]];
- else if ((x < maxPoint) && (bord[x + 1][y] == me))
- myGID = gMap[groupIDs[x + 1][y]];
- else if ((y > 0) && (bord[x][y - 1] == me))
- myGID = gMap[groupIDs[x][y - 1]];
- else if ((y < maxPoint) && (bord[x][y + 1] == me))
- myGID = gMap[groupIDs[x][y + 1]];
- else /* nobody to connect to */
- {
- newGID = newGID + 1;
- isNew = TRUE;
- myGID = newGID;
- gList[myGID].groupMark = 0;
- gList[myGID].atLevel = tryLevel;
- gList[myGID].isLive = FALSE;
- gList[myGID].numEyes = -1;
- gList[myGID].size = -1;
- gList[myGID].lx = x;
- gList[myGID].ly = y;
- gMap[myGID] = myGID;
- }
- groupIDs[x][y] = myGID;
- playMark = playMark + 1;
- /* record this move */
- playStack[playMark].kind = add;
- playStack[playMark].uval.add.who = me;
- playStack[playMark].uval.add.xl = x;
- playStack[playMark].uval.add.yl = y;
- playStack[playMark].gID = myGID;
- playStack[playMark].uval.add.sNumber = 0;
- if (isNew)
- playStack[playMark].uval.add.nextGID = newGID - 1;
- else
- playStack[playMark].uval.add.nextGID = newGID;
- if (showTrees)
- sstone(me, x, y, 0);
- /* merge adjacent groups */
- if ((x > 0) && (bord[x - 1][y] == me) &&
- (gMap[groupIDs[x - 1][y]] != myGID))
- mergeGroup(gMap[groupIDs[x - 1][y]], myGID);
- if ((x < maxPoint) && (bord[x + 1][y] == me) &&
- (gMap[groupIDs[x + 1][y]] != myGID))
- mergeGroup(gMap[groupIDs[x + 1][y]], myGID);
- if ((y > 0) && (bord[x][y - 1] == me) &&
- (gMap[groupIDs[x][y - 1]] != myGID))
- mergeGroup(gMap[groupIDs[x][y - 1]], myGID);
- if ((y < maxPoint) && (bord[x][y + 1] == me) &&
- (gMap[groupIDs[x][y + 1]] != myGID))
- mergeGroup(gMap[groupIDs[x][y + 1]], myGID);
- /* kill opposing groups, listing affected groups */
- nlcGroup.indx = 1;
- nlcGroup.v[1] = myGID; /* init list to include me */
- if ((x > 0) && (bord[x - 1][y] == him) &&
- (gList[gMap[groupIDs[x - 1][y]]].libC == 1))
- {
- killFlag = TRUE;
- killGroup(x - 1, y, me, him);
- }
- if ((x < maxPoint) && (bord[x + 1][y] == him) &&
- (gList[gMap[groupIDs[x + 1][y]]].libC == 1))
- {
- killFlag = TRUE;
- killGroup(x + 1, y, me, him);
- }
- if ((y > 0) && (bord[x][y - 1] == him) &&
- (gList[gMap[groupIDs[x][y - 1]]].libC == 1))
- {
- killFlag = TRUE;
- killGroup(x, y - 1, me, him);
- }
- if ((y < maxPoint) && (bord[x][y + 1] == him) &&
- (gList[gMap[groupIDs[x][y + 1]]].libC == 1))
- {
- killFlag = TRUE;
- killGroup(x, y + 1, me, him);
- }
- /* list groups adjacent to me */
- if ((x > 0) && (bord[x - 1][y] == him))
- {
- nlcGroup.indx = nlcGroup.indx + 1;
- nlcGroup.v[nlcGroup.indx] = gMap[groupIDs[x - 1][y]];
- }
- if ((x < maxPoint) && (bord[x + 1][y] == him))
- {
- nlcGroup.indx = nlcGroup.indx + 1;
- nlcGroup.v[nlcGroup.indx] = gMap[groupIDs[x + 1][y]];
- }
- if ((y > 0) && (bord[x][y - 1] == him))
- {
- nlcGroup.indx = nlcGroup.indx + 1;
- nlcGroup.v[nlcGroup.indx] = gMap[groupIDs[x][y - 1]];
- }
- if ((y < maxPoint) && (bord[x][y + 1] == him))
- {
- nlcGroup.indx = nlcGroup.indx + 1;
- nlcGroup.v[nlcGroup.indx] = gMap[groupIDs[x][y + 1]];
- }
- /* fix liberty count for affected groups */
- grpMark = grpMark + 1;
- for (i = 1; i <= nlcGroup.indx; i++)
- if (gList[nlcGroup.v[i]].groupMark != grpMark)
- {
- if (gList[nlcGroup.v[i]].atLevel != tryLevel)
- {
- playMark = playMark + 1;
- playStack[playMark].kind = chLib;
- playStack[playMark].gID = nlcGroup.v[i];
- playStack[playMark].uval.chLib.oldLevel =
- gList[nlcGroup.v[i]].atLevel;
- playStack[playMark].uval.chLib.oldLC =
- gList[nlcGroup.v[i]].libC;
- }
- gList[nlcGroup.v[i]].groupMark = grpMark;
- gList[nlcGroup.v[i]].atLevel = tryLevel;
- spanGroup(gList[nlcGroup.v[i]].lx, gList[nlcGroup.v[i]].ly, &pPlist);
- gList[nlcGroup.v[i]].libC = pPlist.indx;
- }
- } /* plei */
-
- saveState()
- { /* saveState */
- playMark = 0;
- tryLevel = 0;
- newGID = maxGroupID;
- } /* saveState */
-
- /*
- undoes a move sequence back to uMark
- */
- undoTo(uMark)
- short uMark;
- { /* undoTo */
- short i, xl, yl;
- #ifdef DEBUG
- printf( "undoTo\n" );
- #endif
- for (i = playMark; i >= uMark + 1; i--)
- if (playStack[i].kind == rem)
- {
- xl = playStack[i].uval.rem.xl;
- yl = playStack[i].uval.rem.yl;
- bord[xl][yl] = playStack[i].uval.rem.who;
- groupIDs[xl][yl] = playStack[i].gID;
- if (showTrees)
- sstone(playStack[i].uval.rem.who, xl, yl,
- playStack[i].uval.rem.sNumber);
- }
- else if (playStack[i].kind == add)
- {
- xl = playStack[i].uval.add.xl;
- yl = playStack[i].uval.add.yl;
- bord[xl][yl] = 0;
- groupIDs[xl][yl] = 0;
- tryLevel = tryLevel - 1;
- newGID = playStack[i].uval.add.nextGID;
- if (showTrees)
- rstone(xl, yl);
- }
- else if (playStack[i].kind == reMap)
- gMap[playStack[i].gID] = playStack[i].uval.reMap.oldGID;
- else /* change libs of group - gID is pre-mapped */
- {
- gList[playStack[i].gID].libC = playStack[i].uval.chLib.oldLC;
- gList[playStack[i].gID].atLevel = playStack[i].uval.chLib.oldLevel;
- }
- playMark = uMark;
- } /* undoTo */
-
- /*
- restores the state of the world after trying a move sequence
- */
- restoreState()
- { /* restoreState */
- #ifdef DEBUG
- printf( "restoreState\n" );
- #endif
- if (playMark > 0)
- {
- undoTo(0);
- playMark = 0;
- tryLevel = 0;
- }
- } /* restoreState */
-
- /* exception bpt; */
-
-
- /*
- returns true if (the group (at gx, gy) is saveable.
- if so, returns the point to play at in savex, savey
- */
- short saveable(gx, gy, savex, savey)
- short gx, gy, *savex, *savey;
- { /* saveable */
- short me, him, gx1, gx2, i, j, smark, mark2, tl, result;
- char sChar;
- sPointList dList;
- point tp;
- short libList[maxSPoint+1];
- #ifdef DEBUG
- printf( "saveable\n" );
- #endif
- dbStop = TRUE;
- me = bord[gx][gy];
- him = -me;
- if (me == 1)
- sChar = '|';
- else
- sChar = '>';
- /* write(sChar); */
- spanGroup(gx, gy, &plist3); /* find my liberties */
- if (adjInAtari) /* one of my options is to kill */
- {
- listAdjacents(gx, gy, &aList);
- for (i = 1; i <= aList.indx; i++)
- if (gList[aList.v[i]].libC == 1)
- {
- spanGroup(gList[aList.v[i]].lx, gList[aList.v[i]].ly,
- &pList1); /* find it's liberty */
- plist3.indx = plist3.indx + 1;
- plist3.p[plist3.indx].px = pList1.p[1].px;
- plist3.p[plist3.indx].py = pList1.p[1].py;
- }
- }
- for (i = 1; i <= maxSPoint; i++)
- libList[i] = -1;
- if ((utilPlayLevel > 4) &&
- (gList[gMap[groupIDs[gx][gy]]].libC > 1)) /* account for diags */
- {
- listDiags(gx, gy, &dList);
- j = 0;
- i = plist3.indx;
- while ((j < dList.indx) &&
- (i < maxSPoint))
- {
- j = j + 1;
- i = i + 1;
- libList[i] = 100;
- plist3.p[i].px = dList.p[j].px;
- plist3.p[i].py = dList.p[j].py;
- }
- plist3.indx = i;
- }
- if (plist3.indx > 1) /* sort by decreasing lib count */
- {
- for (i = 1; i <= plist3.indx; i++)
- if (libList[i] != 100)
- {
- mark2 = playMark;
- tryPlay(plist3.p[i].px, plist3.p[i].py, me);
- libList[i] = gList[gMap[groupIDs[gx][gy]]].libC;
- if (libList[i] > treeLibLim) /* i'm safe */
- {
- *savex = plist3.p[i].px;
- *savey = plist3.p[i].py;
- result = TRUE;
- goto one;
- }
- undoTo(mark2);
- }
- for (i = 1; i <= plist3.indx - 1; i++)
- for (j = i + 1; j <= plist3.indx; j++)
- if (libList[i] < libList[j])
- {
- tl = libList[i];
- libList[i] = libList[j];
- libList[j] = tl;
- tp = plist3.p[i];
- plist3.p[i] = plist3.p[j];
- plist3.p[j] = tp;
- }
- }
- for (i = 1; i <= plist3.indx; i++)
- {
- *savex = plist3.p[i].px;
- *savey = plist3.p[i].py;
- if (legal[*savex][*savey])
- {
- smark = playMark;
- tryPlay(*savex, *savey, me);
- pause();
- if (gList[gMap[groupIDs[*savex][*savey]]].libC > 1)
- if (gList[gMap[groupIDs[gx][gy]]].libC > treeLibLim)
- {
- restoreState();
- /* sClearChar(sChar, rXor); */
- return TRUE;
- }
- else if (gList[gMap[groupIDs[gx][gy]]].libC > 1)
- if (! killable(gx, gy, &gx1, &gx2))
- {
- restoreState();
- /* sClearChar(sChar, rXor); */
- return TRUE;
- }
- undoTo(smark);
- }
- }
- result = FALSE;
- one:
- restoreState();
- /* sClearChar(sChar, rXor); */
- return result;
- } /* saveable */
-
- /*
- marks unsavable groups as dead
- */
- markDead()
- { /* markDead */
- short i, j, gx, gy, result;
- #ifdef DEBUG
- printf( "markDead\n" );
- #endif
- for (i = 1; i <= maxGroupID; i++)
- if (killable(gList[i].lx, gList[i].ly, &gx, &gy))
- result = ! saveable(gList[i].lx, gList[i].ly, &gx, &gy);
- else
- result = FALSE;
- for (i = 0; i <= maxPoint; i++)
- for (j = 0; j <= maxPoint; j++)
- if (bord[i][j] == 0)
- ndbord[i][j] = 0;
- else if (gList[groupIDs[i][j]].isDead)
- ndbord[i][j] = 0;
- else
- ndbord[i][j] = bord[i][j];
- } /* markDead */
-
- /*
- marks groups with two eyes as live
- */
- MLspan(x, y, saw1, sawm1, size, sMark)
- short x, y, *saw1, *sawm1, *size, sMark;
- { /* span */
- if (ndbord[x][y] == 1)
- *saw1 = TRUE;
- else if (ndbord[x][y] == -1)
- *sawm1 = TRUE;
- else if (sGroups[x][y] == 0)
- {
- if (sMark<0 || sMark>400) printf("ERROR: %d\n",sMark);
- sGroups[x][y] = sMark;
- *size = *size + 1;
- if (x > 0)
- MLspan(x - 1, y, saw1, sawm1, size, sMark);
- if (x < maxPoint)
- MLspan(x + 1, y, saw1, sawm1, size, sMark);
- if (y > 0)
- MLspan(x, y - 1, saw1, sawm1, size, sMark);
- if (y < maxPoint)
- MLspan(x, y + 1, saw1, sawm1, size, sMark);
- }
- } /* span */
-
- short CLspan(x, y, numEyes, who)
- short x, y, *numEyes, who;
- { /* span */
- markBoard[x][y] = marker;
- if (ndbord[x][y] == 0)
- {
- if ((sList[sGroups[x][y]].sm != marker) &&
- (sList[sGroups[x][y]].w == who))
- {
- sList[sGroups[x][y]].sm = marker;
- if (sList[sGroups[x][y]].s > 6)
- return TRUE;
- *numEyes = *numEyes + 1;
- if (*numEyes > 1)
- return TRUE;
- }
- }
- else if (bord[x][y] == who)
- {
- if ((x > 0) &&
- (markBoard[x - 1][y] != marker))
- if (CLspan(x - 1, y, numEyes, who)) return TRUE;
- if ((x < maxPoint) &&
- (markBoard[x + 1][y] != marker))
- if (CLspan(x + 1, y, numEyes, who)) return TRUE;
- if ((y > 0) &&
- (markBoard[x][y - 1] != marker))
- if (CLspan(x, y - 1, numEyes, who)) return TRUE;
- if ((y < maxPoint) &&
- (markBoard[x][y + 1] != marker))
- if (CLspan(x, y + 1, numEyes, who)) return TRUE;
- }
- return FALSE;
- } /* span */
-
- short checkLive(x, y)
- short x, y;
- { /* checkLive */
- short numEyes, who;
- #ifdef DEBUG
- printf( "checkLive\n" );
- #endif
- numEyes = 0;
- who = bord[x][y];
- marker = marker + 1;
- return CLspan(x, y, &numEyes, who);
- } /* checkLive */
-
- markLive()
- { /* markLive */
- short i, j, size, sMark = 0;
- short saw1, sawm1;
- #ifdef DEBUG
- printf( "markLive\n" );
- #endif
- initArray(sGroups);
- for (i = 0; i <= maxPoint; i++)
- for (j = 0; j <= maxPoint; j++)
- if ((sGroups[i][j] == 0) &&
- (ndbord[i][j] == 0))
- {
- size = 0;
- sMark = sMark + 1;
- sawm1 = FALSE;
- saw1 = FALSE;
- MLspan(i, j, &saw1, &sawm1, &size, sMark);
- sList[sMark].s = size;
- sList[sMark].sm = 0;
- if (sawm1)
- if (saw1)
- sList[sMark].w = 0;
- else
- sList[sMark].w = -1;
- else if (saw1)
- sList[sMark].w = 1;
- else
- sList[sMark].w = 0;
- }
- for (i = 1; i <= maxGroupID; i++)
- if (! gList[i].isDead)
- gList[i].isLive = checkLive(gList[i].lx, gList[i].ly);
- } /* markLive */
-
- /*
- generates the connection map and the protected point map.
- */
- genConnects()
- { /* genConnects */
- short x, y, numStones;
- #ifdef DEBUG
- printf( "genConnects\n" );
- #endif
- for (x = 0; x <= maxPoint; x++)
- for (y = 0; y <= maxPoint; y++)
- {
- connectMap[x][y] = 0;
- protPoints[x][y] = 0;
- }
- for (x = 0; x <= maxPoint; x++)
- for (y = 0; y <= maxPoint; y++)
- if (bord[x][y] == 1) /* map connections to this stone */
- {
- if (x > 0) /* direct connection */
- connectMap[x - 1][y] += 1;
- if (x < maxPoint)
- connectMap[x + 1][y] += 1;
- if (y > 0)
- connectMap[x][y - 1] += 1;
- if (y < maxPoint)
- connectMap[x][y + 1] += 1;
- if ((x > 0) && (y > 0) && /* diagonal connection */
- (bord[x - 1][y] == 0) && (bord[x][y - 1] == 0))
- connectMap[x - 1][y - 1] += 1;
- if ((x < maxPoint) && (y > 0) &&
- (bord[x + 1][y] == 0) && (bord[x][y - 1] == 0))
- connectMap[x + 1][y - 1] += 1;
- if ((x < maxPoint) && (y < maxPoint) &&
- (bord[x + 1][y] == 0) && (bord[x][y + 1] == 0))
- connectMap[x + 1][y + 1] += 1;
- if ((x > 0) && (y < maxPoint) &&
- (bord[x - 1][y] == 0) && (bord[x][y + 1] == 0))
- connectMap[x - 1][y + 1] += 1;
- if ((x > 1) && (claim[x - 1][y] > 3)) /* one point jump */
- connectMap[x - 2][y] += 1;
- if ((x < (maxPoint - 1)) && (claim[x + 1][y] > 3))
- connectMap[x + 2][y] += 1;
- if ((y > 1) && (claim[x][y - 1] > 3))
- connectMap[x][y - 2] += 1;
- if ((y < (maxPoint - 1)) && (claim[x][y + 1] > 3))
- connectMap[x][y + 2] += 1;
- if ((x > 1) && (y > 0) && /* knight's move */
- (claim[x - 1][y] > 3) && (claim[x - 1][y - 1] > 3))
- connectMap[x - 2][y - 1] += 1;
- if ((x > 0) && (y > 1) &&
- (claim[x][y - 1] > 3) && (claim[x - 1][y - 1] > 3))
- connectMap[x - 1][y - 2] += 1;
- if ((x < (maxPoint - 1)) && (y > 0) &&
- (claim[x + 1][y] > 3) && (claim[x + 1][y - 1] > 3))
- connectMap[x + 2][y - 1] += 1;
- if ((x < maxPoint) && (y > 1) &&
- (claim[x][y - 1] > 3) && (claim[x + 1][y - 1] > 3))
- connectMap[x + 1][y - 2] += 1;
- if ((x > 1) && (y < maxPoint) &&
- (claim[x - 1][y] > 3) && (claim[x - 1][y + 1] > 3))
- connectMap[x - 2][y + 1] += 1;
- if ((x > 0) && (y < (maxPoint - 1)) &&
- (claim[x][y + 1] > 3) && (claim[x - 1][y + 1] > 3))
- connectMap[x - 1][y + 2] += 1;
- if ((x < (maxPoint - 1)) && (y < maxPoint) &&
- (claim[x + 1][y] > 3) && (claim[x + 1][y + 1] > 3))
- connectMap[x + 2][y + 1] += 1;
- if ((x < maxPoint) && (y < (maxPoint - 1)) &&
- (claim[x][y + 1] > 3) && (claim[x + 1][y + 1] > 3))
- connectMap[x + 1][y + 2] += 1;
- }
- else if (bord[x][y] == 0) /* see if protected point */
- {
- numStones = 0;
- if (x == 0)
- numStones = numStones + 1;
- if (y == 0)
- numStones = numStones + 1;
- if (x == maxPoint)
- numStones = numStones + 1;
- if (y == maxPoint)
- numStones = numStones + 1;
- if ((x > 0) && (bord[x - 1][y] == 1))
- numStones = numStones + 1;
- if ((y > 0) && (bord[x][y - 1] == 1))
- numStones = numStones + 1;
- if ((x < maxPoint) && (bord[x + 1][y] == 1))
- numStones = numStones + 1;
- if ((y < maxPoint) && (bord[x][y + 1] == 1))
- numStones = numStones + 1;
- if (numStones == 4)
- protPoints[x][y] = 1;
- else if (numStones == 3)
- {
- if ((x > 0) &&
- ((bord[x - 1][y] == 0) ||
- ((bord[x - 1][y] == -1) &&
- (gList[groupIDs[x - 1][y]].libC == 1))))
- protPoints[x][y] = 1;
- else if ((x < maxPoint) &&
- ((bord[x + 1][y] == 0) ||
- ((bord[x + 1][y] == -1) &&
- (gList[groupIDs[x + 1][y]].libC == 1))))
- protPoints[x][y] = 1;
- else if ((y > 0) &&
- ((bord[x][y - 1] == 0) ||
- ((bord[x][y - 1] == -1) &&
- (gList[groupIDs[x][y - 1]].libC == 1))))
- protPoints[x][y] = 1;
- else if ((y < maxPoint) &&
- ((bord[x][y + 1] == 0) ||
- ((bord[x][y + 1] == -1) &&
- (gList[groupIDs[x][y + 1]].libC == 1))))
- protPoints[x][y] = 1;
- }
- }
- for (x = 0; x <= maxPoint; x++)
- for (y = 0; y <= maxPoint; y++)
- if (bord[x][y] != 0)
- {
- connectMap[x][y] = 0;
- protPoints[x][y] = 0;
- }
- } /* genConnects */
-
- /*
- generates the whole state of the game.
- */
- genState()
- { /* genState */
- #ifdef DEBUG
- printf( "genState\n" );
- #endif
- inGenState = TRUE;
- respreicen();
- markDead();
- markLive();
- spread();
- genConnects();
- #ifdef DEBUG
- /* printBoard( claim, "claim" ); */
- /* printBoard( bord, "bord" ); */
- /* printBoard( ndbord, "ndbord" );
- printBoard( sGroups, "sGroups" );
- printBoard( groupIDs, "groupIDs" );
- printBoard( connectMap, "connectMap" );
- printBoard( protPoints, "protPoints" ); */
- #endif
- inGenState = FALSE;
- } /* genState */
-
- /*
- generates a value for the [x, y] location that appears to get larger
- for points that are saddle points in the influence graph (klein)
- */
- short tencen(x, y)
- short x, y;
- { /* tencen */
- short a, b, c, d, w, z;
- #ifdef DEBUG
- printf( "tencen\n" );
- #endif
- if (claim[x][y] > -1) /* if (he does not influence this area, return 50 */
- {
- return 50;
- }
- w = claim[x][y]; /* w <= -1 */
- a = iNil;
- if (x > 0)
- if (claim[x - 1][y] > -1) /* if (neighbor is not influenced by him */
- a = claim[x - 1][y] - w; /* score is sum of his influence on central */
- b = iNil; /* point and my influence on this neighbor */
- if (y > 0)
- if (claim[x][y - 1] > -1)
- b = claim[x][y - 1] - w;
- c = iNil;
- if (x < maxPoint)
- if (claim[x + 1][y] > -1)
- c = claim[x + 1][y] - w;
- d = iNil;
- if (y < maxPoint)
- if (claim[x][y + 1] > -1)
- d = claim[x][y + 1] - w;
- z = a; /* z = max(a, b, c, d) */
- if (z != iNil)
- {
- if ((b != iNil) &&
- (b > z))
- z = b;
- }
- else
- z = b;
- if (z != iNil)
- {
- if ((c != iNil) &&
- (c > z))
- z = c;
- }
- else
- z = c;
- if (z != iNil)
- {
- if ((d != iNil) &&
- (d > z))
- z = d;
- }
- else
- z = d;
- if ((z != iNil) &&
- ((x == 0) ||
- (y == 0) ||
- (x == maxPoint) ||
- (y == maxPoint)))
- z = z * 2; /* double z if (on the edge of the board ?? */
- if (z != iNil)
- return z;
- else
- return 50;
- } /* tencen */
-
- initGPUtils()
- { /* initGPUtils */
- #ifdef DEBUG
- printf( "initGPUtils\n" );
- #endif
- initArray(markBoard);
- initState();
- marker = 0;
- playMark = 0;
- gList[0].isLive = FALSE;
- gList[0].isDead = FALSE;
- gList[0].libC = 0;
- gList[0].size = 0;
- gList[0].numEyes = 0;
- gList[0].lx = -1;
- gList[0].ly = -1;
- gMap[0] = 0;
- dbStop = FALSE;
- inGenState = FALSE;
- } /* initGPUtils */
-
-